@page "/json"
@using System.Text.Json
@inject IJSRuntime JSRuntime

<h2>JSON performance</h2>

<p><button id="reset-all" @onclick=Reset>Reset</button></p>

<button id="serialize-small" @onclick=SerializeSmall>Serialize (small)</button>
<button id="serialize-large" @onclick=SerializeLarge>Serialize (large)</button>

<p><pre style="border: 1px solid black; overflow: scroll;">@serializedValue</pre></p>
@if (serializedValue != null)
{
    <p>Serialized length: <strong id="serialized-length">@serializedValue.Length</strong> chars</p>
}

<button id="deserialize-small" @onclick=DeserializeSmall>Deserialize (small)</button>
<button id="deserialize-large" @onclick=DeserializeLarge>Deserialize (large)</button>

@if (numPeopleDeserialized > 0)
{
    <p>Deserialized <strong id="deserialized-count">@numPeopleDeserialized</strong> people</p>
}

@code {
    Person smallOrgChart = Person.GenerateOrgChart(1, 4);
    Person largeOrgChart = Person.GenerateOrgChart(5, 4);
    string smallOrgChartJson;
    string largeOrgChartJson;
    int numPeopleDeserialized;

    protected override void OnInitialized()
    {
        smallOrgChartJson = JsonSerializer.Serialize(smallOrgChart);
        largeOrgChartJson = JsonSerializer.Serialize(largeOrgChart);
    }

    protected override void OnAfterRender(bool firstRender)
    {
        BenchmarkEvent.Send(JSRuntime, "Finished JSON processing");
    }

    string serializedValue;

    void Reset()
    {
        serializedValue = null;
        numPeopleDeserialized = 0;
    }

    void SerializeSmall()
        => serializedValue = JsonSerializer.Serialize(smallOrgChart);

    void SerializeLarge()
        => serializedValue = JsonSerializer.Serialize(largeOrgChart);

    void DeserializeSmall()
        => numPeopleDeserialized = Deserialize(smallOrgChartJson);

    void DeserializeLarge()
        => numPeopleDeserialized = Deserialize(largeOrgChartJson);

    static int Deserialize(string json)
    {
        var ceo = JsonSerializer.Deserialize<Person>(json);
        return CountPeople(ceo);
    }

    static int CountPeople(Person root)
        => 1 + (root.Subordinates?.Sum(CountPeople) ?? 0);
}
